const jwt = require('jsonwebtoken');
const speakeasy = require('speakeasy');
const QRCode = require('qrcode');
const moment = require('moment');
const crypto = require('crypto');
const uuidv1 = require('uuid');
const BigNumber = require('bignumber.js');
const bcrypt = require('bcrypt');
const svgCaptcha = require('svg-captcha');
const svgToImg = require("svg-to-img");




exports.createCipher = function(pt){
    if(!pt){
        return pt;
    }
    const key = 'sdfkshfkh((((9999esSHKSwww...mobai';
    let encrypt = crypto.createCipher('aes256', key);
    let encrypted = encrypt.update(pt, 'utf8', 'hex');
    encrypted += encrypt.final('hex');
    return encrypted;
};

exports.createDecipher = function(encrypted){
    if(!encrypted){
        return encrypted;
    }
    const key = 'sdfkshfkh((((9999esSHKSwww...mobai';
    var decrypt = crypto.createDecipher('aes256', key);
    var decrypted = decrypt.update(encrypted, 'hex', 'utf8');
    decrypted += decrypt.final();
    return decrypted;
};



exports.md5PWD = function(password){
    if(!password){
        return password;
    }
    return crypto.createHash('md5').update(password).digest('hex');
};

exports.md5Hex = function(volunteerNo,password){
    let salt = volunteerNo.substring(2,4).concat(password).concat(volunteerNo.substring(6,8));
    let obj = crypto.createHash('md5');
    obj.update(salt);
    let strHex = obj.digest('hex');
    return strHex;
};

exports.matchesPassword = function(rawPassword,encodedPassword){
    return new Promise(function (resolve, reject) {
        bcrypt.compare(rawPassword, encodedPassword, function (err, result) {
            resolve(result)
        });
    })
};

exports.bcryptHashPassword = function(myPlaintextPassword){
    return new Promise(function (resolve, reject) {
        bcrypt.hash(myPlaintextPassword,10, function (err, hash) {
            resolve(hash);
        });
    });
};

exports.checkEmail = function (email) {
    if (!email) {
        return false
    }
    var myreg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
    if (!myreg.test(email)) {
        console.info('checkEmail:', email)
        return false;

    } else {

        return true;

    }
};

exports.signToken = function (user_id,password) {
    let token = jwt.sign({user_id: user_id, ts: new Date().getTime()}, '8ce0770e-5813-cf29-f866-af0c147c8053'+"_"+password);
    return token
};

exports.verifyToken = function (token,password) {
    return new Promise(function (resolve, reject) {
        jwt.verify(token, '8ce0770e-5813-cf29-f866-af0c147c8053'+"_"+password, function (err, decoded) {
            if (err || !decoded) {
                resolve(null);
            } else {
                resolve(decoded)
            }
        });
    });
};

exports.signTokenExp = function(email,code){
    let token = jwt.sign({
        exp: Math.floor(Date.now() / 1000) + (60 * 30),
        data: {
            email:email,
            code:code
        }
    }, '8ce0770e-5813-cf29-f866-af0c147c8053'+"_"+email);
    return token;
};



exports.generateGoogleQRCode = function (name) {
    return new Promise(function (resolve, reject) {
        const secret = speakeasy.generateSecret({
            length: 20,
            name: `Goldkey:(${name}-${moment().format('YYYY-MM-DD')})`
        });
        let two_factor_temp_secret = secret.base32;
        let otpauth_url = secret.otpauth_url;
        QRCode.toDataURL(otpauth_url, function (err, data_url) {
            if (err) {
                console.error(`generateGoogleQRCode error:`, err.message);
                reject(err);
            } else {
                const res = {
                    secret_key: two_factor_temp_secret,
                    qr_code: data_url,
                    otpauth_url: otpauth_url
                };
                resolve(res);
            }
        });
    });
};

exports.verifyGoogleAuthenticator = function (token, secret) {
    const verified = speakeasy.totp.verify({
        secret: secret,
        encoding: 'base32',
        token: token
    });
    return verified;
};

exports.getTokenKey = function (type) {
    const s = uuidv1.v1();
    const hmac = crypto.createHmac('sha256', s + new Date().getTime() + Math.floor(Math.random() * 100000000) + type);
    hmac.update(s + type);
    return hmac.digest('hex');
};

/**
 * 加
 * @param x
 * @param y
 * @returns {number}
 */
exports.bigNumberPlus = function (x, y, n) {
    let a = new BigNumber(x);
    let b = new BigNumber(y);
    let c = a.plus(b);
    c = c.toNumber();
    if (n) {
        c = Math.floor(c * (Math.pow(10, n))) / (Math.pow(10, n));
        //c = c.toFixed(n);
        //c = parseFloat(c);
    }
    return c;
};

/**
 * 减
 * @param x
 * @param y
 * @returns {number}
 */
exports.bigNumberMinus = function (x, y, n) {
    let a = new BigNumber(x);
    a = a.minus(y);
    a = a.toNumber();
    if (n) {
        a = Math.floor(a * (Math.pow(10, n))) / (Math.pow(10, n));
        //a = a.toFixed(n);
        //a = parseFloat(a);
    }
    return a;
};

/**
 * 乘
 * @param x
 * @param y
 * @returns {number}
 */
exports.bigNumberMultipliedBy = function (x, y, n) {
    let a = new BigNumber(x);
    let b = a.multipliedBy(y);
    b = b.toNumber();
    if (n) {
        b = Math.floor(b * (Math.pow(10, n))) / (Math.pow(10, n));
        b = b.toFixed(n);
        //b = parseFloat(b);
    }
    return b;
};

/**
 * 除
 * @param x
 * @param y
 * @returns {number}
 */
exports.bigNumberDiv = function (x, y, n) {
    let a = new BigNumber(x);
    a = a.div(y);
    a = a.toNumber();
    if (n) {
        a = Math.floor(a * (Math.pow(10, n))) / (Math.pow(10, n));
        //a = a.toFixed(n);
        //a = parseFloat(a);
    }
    return a;
};

exports.toFloor = function (num, n = 2) {
    if (isNaN(num)) {
        return 0;
    }
    num = parseFloat(num);
    let d =  Math.floor(num * (Math.pow(10, n))) / (Math.pow(10, n));
    return d.toFixed(n);
};

exports.getNowDate = function () {
    var date = new Date();
    var sign1 = "-";
    var sign2 = ":";
    var year = date.getFullYear() // 年
    var month = date.getMonth() + 1; // 月
    var day = date.getDate(); // 日

    // 给一位数数据前面加 “0”
    if (month >= 1 && month <= 9) {
        month = "0" + month;
    }
    if (day >= 0 && day <= 9) {
        day = "0" + day;
    }
    var currentdate = year + sign1 + month + sign1 + day;
    return currentdate;
};


exports.captchaImage = function () {
    return new Promise(function (resolve, reject) {
        let captcha = svgCaptcha.create({background:'#e9e4e4',ignoreChars: '0O1I',color:false,ignoreChars:'0o1i',noise:3,size:4});
        /*svgToImg.from(captcha.data).toPng({
            encoding: "base64"
        }).then(function (res) {
            resolve({
                data:res,
                text:captcha.text
            });
        })*/
        resolve({
            data:captcha.data,
            text:captcha.text
        });
      /*  resolve({
            data:res,
            text:captcha.text
        });
       console.log(captcha)*/
    });
};